package com.prawn.authority.service;

import java.util.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.prawn.authority.utils.GlobalException;
import entity.Result;
import entity.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import util.IdWorker;

import com.prawn.authority.dao.RoleDao;
import com.prawn.authority.pojo.Role;

/**
 * 服务层
 *
 * @author Administrator
 *
 */
@Service
public class RoleService {

	@Autowired
	private RoleDao roleDao;

	@Autowired
	private IdWorker idWorker;

	/**
	 * 查询全部列表
	 * @return
	 */
	public List<Role> findAll() {
		return roleDao.findAll();
	}

	/**
	 * 条件查询+分页
	 * @param whereMap
	 * @param page
	 * @param size
	 * @return
	 */
	public Page<Role> findSearch(Map whereMap, int page, int size) {
		Specification<Role> specification = createSpecification(whereMap);
		PageRequest pageRequest =  PageRequest.of(page-1, size);
		return roleDao.findAll(specification, pageRequest);
	}

	/**
	 * 条件查询
	 * @param whereMap
	 * @return
	 */
	public List<Role> findSearch(Map whereMap) {
		Specification<Role> specification = createSpecification(whereMap);
		return roleDao.findAll(specification);
	}

	/**
	 * 根据ID查询实体
	 * @param id
	 * @return
	 */
	public Role findById(String id) {
		Optional<Role> role = roleDao.findById(id);
		// 若为空就抛出错误
		if(!role.isPresent()){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "角色不存在"));
		}
		return role.get();
	}

	/**
	 * 增加
	 * @param role
	 */
	public void add(Role role) {
		try {
			role.setId( idWorker.nextId()+"" );
			role.setCreateDate(new Date());
			roleDao.save(role);
		}catch(DataIntegrityViolationException e){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "角色已存在或角色名为空"));
		}catch(Exception e){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "添加失败"));
		}
	}

	/**
	 * 修改
	 * @param role
	 */
	public void update(Role role) {
		if(role.getId().equals("1266706569211547649")){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "请勿修改超级管理员"));
		}
		Role roleLogin = findById(role.getId());
		if(roleLogin == null){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "角色不存在"));
		}else{
			try {
				role.setName(role.getName() == null ? roleLogin.getName() : role.getName());
				role.setRemarks(role.getRemarks() == null ? roleLogin.getRemarks() : role.getRemarks());
				role.setRemarks(role.getRemarks() == null ? roleLogin.getRemarks() : role.getRemarks());
				roleDao.save(role);
			}catch(DataIntegrityViolationException e){
				throw new GlobalException(new Result(false, StatusCode.ERROR, "角色名称已存在"));
			}catch(Exception e){
				throw new GlobalException(new Result(false, StatusCode.ERROR, "修改失败"));
			}
		}
	}

	/**
	 * 删除
	 * @param id
	 */
	public void deleteById(String id) {
		if(id.equals("1266706569211547649")){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "请勿删除超级管理员"));
		}
		try {
			roleDao.deleteById(id);
		}catch(EmptyResultDataAccessException e){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "角色不存在"));
		}catch (Exception e){
			throw new GlobalException(new Result(false, StatusCode.ERROR, "删除失败"));
		}
	}

	/**
	 * 查询该管理员尚未被赋予的角色
	 */
	public List<Role> findOthersByUserId(String userId){
		return roleDao.findOthersByUserId(userId);
	}

	/**
	 * 查询该管理员尚已赋予的角色
	 */
	public List<Role> findRoleByUserId(String userId){
		return roleDao.findByUserId(userId);
	}

	/**
	 * 动态条件构建
	 * @param searchMap
	 * @return
	 */
	private Specification<Role> createSpecification(Map searchMap) {

		return new Specification<Role>() {

			@Override
			public Predicate toPredicate(Root<Role> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicateList = new ArrayList<Predicate>();
                // id
                if (searchMap.get("id")!=null && !"".equals(searchMap.get("id"))) {
                	predicateList.add(cb.like(root.get("id").as(String.class), "%"+(String)searchMap.get("id")+"%"));
                }
                // 角色名称
                if (searchMap.get("name")!=null && !"".equals(searchMap.get("name"))) {
                	predicateList.add(cb.like(root.get("name").as(String.class), "%"+(String)searchMap.get("name")+"%"));
                }
                // 是否可用
                if (searchMap.get("useable")!=null && !"".equals(searchMap.get("useable"))) {
					predicateList.add(cb.equal(root.get("useable"), searchMap.get("useable")));
                }
                // 备注信息
                if (searchMap.get("remarks")!=null && !"".equals(searchMap.get("remarks"))) {
                	predicateList.add(cb.like(root.get("remarks").as(String.class), "%"+(String)searchMap.get("remarks")+"%"));
                }

				return cb.and( predicateList.toArray(new Predicate[predicateList.size()]));
			}
		};
	}
}
